package com.carleasoft.mps.core.utils;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author taoyujing
 * @date 2022-01-20 14:46
 * @project service
 */
public class ColumnUtil {
    public static <T> String getName(SFunction<T, ?> fn) {
        // 从function取出序列化方法
        Method writeReplaceMethod;
        try {
            writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        // 从序列化方法取出序列化的lambda信息
        boolean isAccessible = writeReplaceMethod.isAccessible();
        writeReplaceMethod.setAccessible(true);
        SerializedLambda serializedLambda;
        try {
            serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        writeReplaceMethod.setAccessible(isAccessible);

        // 从lambda信息取出method、field、class等
        String fieldName = serializedLambda.getImplMethodName().substring("get".length());
        return fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
    }

    @SafeVarargs
    public static <T> String[] getName(SFunction<T, ?>... fn) {
        String[] res = new String[fn.length];
        for (int i = 0; i < fn.length; i++) {
            // 从function取出序列化方法
            Method writeReplaceMethod;
            try {
                writeReplaceMethod = fn[i].getClass().getDeclaredMethod("writeReplace");
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }

            // 从序列化方法取出序列化的lambda信息
            boolean isAccessible = writeReplaceMethod.isAccessible();
            writeReplaceMethod.setAccessible(true);
            SerializedLambda serializedLambda;
            try {
                serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn[i]);
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            writeReplaceMethod.setAccessible(isAccessible);

            // 从lambda信息取出method、field、class等
            String fieldName = serializedLambda.getImplMethodName().substring("get".length());
            res[i] = (fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase()));
        }
       return res;
    }
}
